www.gusucode.com > 串口测试程序,用于调试rs485接口 串口通信的程序 > 串口测试程序,用于调试rs485接口 串口通信的程序/commtest/Text2.cpp
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/select.h> #include <sys/shm.h> #include <sys/types.h> #include <sys/ipc.h> #include "MyCom.h" #include <termios.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/file.h> /* flock(int fd,int operation)函数 */ using namespace std; const char *MyCom::Serial_Ctl_No[MAX_COMS] = { "/dev/wfet1000com0", "/dev/wfet1000com1", "/dev/wfet1000com2", "/dev/nothing4", "/dev/nothing5", "/dev/nothing6" }; MyCom::MyCom() { if(!CreateSem( COM2 )) { } } MyCom::MyCom(enum COM_NO com) { if(!CreateSem( com )) { } } MyCom::MyCom(BYTE com) { enum COM_NO com_no; AttachComNo( com , com_no); if(!CreateSem( com_no )) { } } bool MyCom::CreateSem(enum COM_NO com) { union semun sem_union; sem_id = semget( (key_t)(SEM_KEY_COM + com), 1, 0666 | IPC_CREAT ); cur_serial_num = com; serial_ctrl_no = 0; if( !AttachSem( 0 ) ) return false; if(com_buf[0] == 1 || com_buf[0] == 2 || com_buf[0] == 3) {//串行口的读写控制1:自动;2、3、非自动;2:读、3:写。表示串行口的信号量已初始化 m_port_status = com_buf[0]; return true; } com_buf[0] = 1; m_port_status = 1; //系统默认为自动收发 sem_union.val=1; if(semctl(sem_id, 0, SETVAL, sem_union )==-1) { return false; } return true; } bool MyCom::OpenCtrl() { // if( m_port_status == com_buf[0] ) return true;//系统的收发控制状态一致、不用再控制 if( serial_ctrl_no <= 0) { serial_ctrl_no = open(Serial_Ctl_No[ cur_serial_num ], O_WRONLY | O_NOCTTY); } return (serial_ctrl_no > 0)? true : false; } bool MyCom::CloseCtrl() { if (serial_ctrl_no > 0) { close(serial_ctrl_no); serial_ctrl_no = 0; } return true; } bool MyCom::SetPortState(enum PORT_STATE m_status)//TRUE 表示发送, FALSE 为接收 { if( m_port_status == com_buf[0] ) return true;//系统的收发控制状态一致、不用再控制 OpenCtrl(); unsigned char str[2]; switch(m_status) { case STATUS_READ: str[0] = 0x00; str[1] = 0x00; break; case STATUS_WRITE: str[0] = 0x01; str[1] = 0x00; break; case STATUS_AUTO: default: str[0] = 0x00; str[1] = 0x01; break; } if(serial_ctrl_no <= 0) return false; if (write(serial_ctrl_no,str,2) <0 ) { CloseCtrl(); return false; } CloseCtrl(); com_buf[0] = (BYTE)m_status; m_port_status = com_buf[0]; return true; } bool MyCom::AttachSem(int flag) { com_id=shmget( (key_t)MEM_KEY_COM + cur_serial_num, sizeof(BYTE), 0666 | IPC_CREAT ); if ( com_id ==-1 ) { return false; } com_addr = shmat(com_id, NULL, flag ); if (com_addr == (void *)-1 ) { return false; } com_buf = (BYTE *) com_addr; return true; } void MyCom::Init_Serial(METERCOMPARA com_para) { switch( (int)com_para.baudrate ) {// case 1: cur_baudrate = B300; break; case 2: cur_baudrate = B600; break; case 4: cur_baudrate = B1200; break; case 8: cur_baudrate = B2400; break; case 16: cur_baudrate = B4800; break; case 32: cur_baudrate = B9600; break; default: cur_baudrate = B9600; break; } switch( (int)com_para.bytesize ) {//COM_BYTESIZE5 = 5,COM_BYTESIZE6 = 6,COM_BYTESIZE7 = 7,COM_BYTESIZE8 = 8 case 5: cur_bytesize = COM_BYTESIZE5 ; break; case 6: cur_bytesize = COM_BYTESIZE6 ; break; case 7: cur_bytesize = COM_BYTESIZE7 ; break; case 8: cur_bytesize = COM_BYTESIZE8 ; break; default: cur_bytesize = COM_BYTESIZE8 ; break; } switch( (int)com_para.parity ) {// PARITY_ODD=0, PARITY_EVEN=1, PARITY_NONE=2 case 0: cur_parity = PARITY_NONE; break; case 1: cur_parity = PARITY_EVEN; break; case 2: cur_parity = PARITY_ODD; break; default: cur_parity = PARITY_EVEN; break; } switch( (int)com_para.stopbits ) { case 0: cur_stopbits = COM_STOPBITS1; break; case 1: cur_stopbits = COM_STOPBITS15; break; case 2: cur_stopbits = COM_STOPBITS2; default: cur_stopbits = COM_STOPBITS1; break; } cur_sync_mode = COM_BLOCK ; //SerialCom::serial_sync_mode(COM_BLOCK); } bool MyCom::sem_serial_open() { if(! sem_P()) { return false; } if(!serial_open()) { // sem_V(); sem_serial_close(); return false; } // OpenCtrl(); return true; } void MyCom::sem_serial_close() { // CloseCtrl(); serial_close() ; sem_V(); } bool MyCom::wait_for_response(int sec_time) { static fd_set readfs; static struct timeval timeout; timeout.tv_usec = 0; timeout.tv_sec = sec_time; /* 设定超时时间为sec_time秒 */ // SetPortState( STATUS_READ ); //设置为读状态 FD_ZERO(&readfs); FD_SET(serial_fd, &readfs); /* 等待数据返回并判断是否超时 */ if (select(serial_fd+1, &readfs, NULL, NULL, &timeout) <= 0) { return false; } /* 读句柄集合里是否是fd句柄来数据 */ if (FD_ISSET(serial_fd, &readfs) <= 0) { tcflush(serial_fd, TCIOFLUSH); return false; } return true; } bool MyCom::change_port(enum COM_NO com) //改变对象使用端口 { SerialCom::change_port( com ); if(!CreateSem( com )) { return false; } return true; } //信号量P操作 bool MyCom::sem_P() { struct sembuf sem_b; if( sem_id==-1 ) { return false; } sem_b.sem_num = 0; sem_b.sem_op = -1; /*p()*/ sem_b.sem_flg = SEM_UNDO; if( semop(sem_id, &sem_b, 1) == -1 ) { return false; } return true; } //信号量V操作 bool MyCom::sem_V() { struct sembuf sem_b; if( sem_id==-1 ) { return false; } sem_b.sem_num = 0; sem_b.sem_op = 1; /*v()*/ sem_b.sem_flg = SEM_UNDO; if( semop(sem_id, &sem_b, 1) == -1 ) { return false; } return true; } //销毁信号量对象 void MyCom::DestroySem() { // shmctl( com_id, IPC_RMID, 0 ); // CloseCtrl(); if (com_addr == (void *) -1 ) { return; } shmdt(com_addr); // semctl( sem_id, 0, IPC_RMID); } int MyCom::serial_read(unsigned char * buf, int len) { return SerialCom::serial_read( buf, len); } int MyCom::serial_write(unsigned char * buf, int len) { SetPortState( STATUS_WRITE ); int Len = SerialCom::serial_write( buf, len); SetPortState( STATUS_READ ); return Len; } bool MyCom::AttachComNo(BYTE com_no,enum COM_NO &com) { switch(com_no) { case 0: com = COM1; break; case 1: com = COM2; break; case 2: com = COM3; break; case 3: com = COM4; break; case 4: com = COM5; break; case 5: com = COM6; break; case 6: com = COM7; break; case 7: com = COM8; break; default: com = COM2; return false; } return true; } bool MyCom::change_port(BYTE com) { enum COM_NO com_no; if(!AttachComNo( com, com_no))//bool AttachComNo(BYTE com_no,enum COM_NO &com); return false; return change_port( com_no ); }